﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Core.h".
//-------------------------------------------------------------------

#ifndef _UXS_MATH_FORWARD_DECL_H
#define _UXS_MATH_FORWARD_DECL_H

#pragma once

#include "../BaseTypes/Types.h"

namespace UX_STL
{
namespace UXMath
{
	

	//
	// Constants
	//

	template <typename T>	constexpr	inline T		Pi ();
	template <typename T>	constexpr	inline T		Exp ();
	template <typename T>	constexpr	inline T		ReciporalPi ();
	template <typename T>				inline T		HalfPi ();
	template <typename T>	constexpr	inline T		Sqrt_2 ();
	template <typename T>	constexpr	inline T		Sqrt_3 ();
	template <typename T>	constexpr	inline T		Sqrt_5 ();
	template <typename T>	constexpr	inline T		Sqrt_10 ();



	//
	// Trigonometry
	//
	
	template <typename T>				inline T		DTR (const T& x);	// Deg To Rad
	template <typename T>				inline T		RTD (const T& x);	// Rad To Deg

	template <typename T>				inline T		Sin (const T& x);
	template <typename T>				inline T		Cos (const T& x);
	//template <typename T>				inline void		SinCos (const T& x, T& s, T& c);

	template <typename T>				inline T		ASin (const T& x);
	template <typename T>				inline T		ACos (const T& x);
	//template <typename T>				inline void		ASinCos (const T& x, T& s, T& c);

	template <typename T>				inline T		SinH (const T& x);
	template <typename T>				inline T		CosH (const T& x);
	//template <typename T>				inline void		SinCosH (const T& x, T& s, T& c);

	template <typename T>				inline T		ASinH (const T& x);
	template <typename T>				inline T		ACosH (const T& x);
	//template <typename T>				inline void		ASinCosH (const T& x, T& s, T& c);

	template <typename T>				inline T		Tan (const T& x);
	template <typename T>				inline T		CoTan (const T& x);

	template <typename T>				inline T		ATan (const T& y_over_x);
	template <typename T>				inline T		ATan (const T& y, const T& x);
	template <typename T>				inline T		ACoTan (const T& x);

	template <typename T>				inline T		ATanH (const T& x);
	template <typename T>				inline T		ACoTanH (const T& x);



	//
	// Copare operations
	//
	
	template <typename T>				inline bool		All (const T& x);
	template <typename T>				inline bool		Any (const T& x);
	template <typename T>				inline bool		Most (const T& x);
	template <typename T>				inline bool		IsZero (const T& x);
	template <typename T>				inline bool		IsNotZero (const T& x);
	template <typename T>				inline bool		Equals (const T& a, const T& b);
	template <typename T>				inline bool		Equals (const T& a, const T& b, const uint& accuracy);
	/*template <typename T>				inline T		Max (const T& a, const T& b);
	template <typename T>				inline T		Max (const T& a, const T& b, const T& c);
	template <typename T>				inline T		Max (const T& a, const T& b, const T& c, const T& d);
	template <typename T>				inline T		Min (const T& a, const T& b);
	template <typename T>				inline T		Min (const T& a, const T& b, const T& c);
	template <typename T>				inline T		Min (const T& a, const T& b, const T& c, const T& d);
	template <typename T>				inline T		MinAbs (const T& a, const T& b);
	template <typename T>				inline T		MaxAbs (const T& a, const T& b);
	template <typename T>				inline void		MinMax (OUT T& tMin, OUT T& tMax, const T& a, const T& b);
	template <typename T>				inline T		MinMag (const T& a, const T& b);
	template <typename T>				inline T		MaxMag (const T& a, const T& b);
	template <typename T>				inline T		MediumValue (const T& a, const T& b);
	template <typename T>				inline T		Mid (const T& a, const T& b, const T& c);
	template <typename T>				inline T		Clamp (const T& val, const T& tMin, const T& tMax);
	template <typename T>				inline T		ClampOut (const T& val, const T& tLeft, const T& tRight);*/
	


	//
	// Operation with sign
	//

	template <typename T>				inline T		Abs (const T& x);
	template <typename T>				inline T		SetSign (const T &x, bool bSign = true);
	template <typename T>				inline T		CopySign (const T& from, const T& to);
	template <typename T>				inline int		Sign (const T& x);
	template <typename T>				inline int		SignOrZero (const T& x);



	//
	// Pow, Exp
	//

	template <int I, typename T>		inline T		Pow (const T& x);
	template <typename T, typename B>	inline T		Pow (const T&x, const B& y);
	template <typename R, typename T>	inline R		Pow2 (const int& p);
	template <typename R>				inline R		Pow2 (const int& p);
	template <typename R>				inline R		Pow10 (int p);
	template <typename T>				inline T		Ln (const T& x);
	template <uint Base, typename T>	inline T		Log (const T& x);
	template <typename T>				inline T		Log (const T& x, const T& base);
	template <typename T>				inline T		Log2 (const T& x);
	template <typename T>				inline T		Log10 (const T& x);
	template <typename T>				inline T		Exp (const T& x);
	template <typename T>				inline T		Exp2 (const T& x);
	template <typename T>				inline T		Exp10 (const T& x);
	template <typename T>				inline uint		PowerOfTwo (const T &x);
	template <typename T>				inline T		CeilPowerOfTwo (const T& x);
	template <typename T>				inline T		FloorPowerOfTwo (const T& x);
	template <typename T>				inline T		NearPowerOfTwo (const T& x);
	template <typename T>				inline bool		IsPowerOfTwo (const T& x);
	template <typename T>				inline T		Square (const T& x);
	template <typename T>				inline T		Sqrt (const T& x);
	template <typename T>				inline T		SquareSign (const T& x);
	template <typename T>				inline T		InvSqrt (const T& x);



	//
	// Interpolation
	//

	template <typename T>				inline T		GetInterpolation (const T& x, const T& y, const T& interpolated);

	template <typename T, typename B>	inline T		Mix (const T& x, const T& y, const B& a);
	template <typename T, typename B>	inline T		QMix (const T& x, const T& y, const T& z, const B& a);
	template <typename T, typename B>	inline T		BiMix (const T v[4], const B& a);
	template <typename T, typename B>	inline T		BiMix (const T& v0, const T& v1, const T& v2, const T& v3, const B& a2);
	template <typename T, typename B>	inline T		BiMix (const T& v0, const T& v1, const T& v2, const T& v3, const B& a0, const B& a1);
	template <typename T, typename B>	inline T		TriMix (const T v[8], const B& a3);
	template <typename T, typename B>	inline T		TriMix (const T &v0, const T &v1, const T &v2, const T &v3, const T &v4, const T &v5, const T &v6, const T &v7, const B& a3);


	
	//
	// Other
	//

	template <typename T>				inline T		Floor (const T& x);
	template <typename T>				inline T		Ceil (const T& x);
	template <typename T>				inline T		Fract (const T& x);
	template <typename R, typename T>	inline R		Round (const T& x);
	template <typename T>				inline bool		IsOdd (const T& x);
	template <typename T>				inline bool		IsEven (const T& x);
	template <typename T>				inline bool		CheckValue (const T& x);

	template <typename T>				inline T		SafeDiv (const T& left, const T& right, const T& defVal = T(0));


	//
	// Bit Operators
	//

	template <typename T, typename B>	inline T		ToBit (const B bitIndex);
	template <typename T, typename B>	inline T		ToMask (const B bitIndex);
	template <typename T>				inline T		GetMaskForType (const T &type = T());

	template <typename T, typename B>	inline T		SafeLeftBitShift (const T& x, const B& shift);	// <<
	template <typename T, typename B>	inline T		SafeRightBitShift (const T& x, const B& shift);	// >>
	
	template <typename T, typename B>	inline T		BitRotateLeft (const T& x, const B& shift);
	template <typename T, typename B>	inline T		BitRotateRight (const T& x, const B& shift);
	
	//template <typename T, typename B>	inline typename TypeDescriptor::MainType<T,B>::type
	//													Mod(const T& left, const B& right);


//-------------------------------------------------------------------

}	// UXMath
}	// UX_STL

#endif	// _UXS_MATH_FORWARD_DECL_H